package Encrypted

import (
	"bytes"
	"crypto/aes"
	"crypto/cipher"
	"encoding/base64"
	"errors"
)

/**
aes 加密
@param key string 密钥
@parma iv string 向量
@param data 数据
*/
func AesEncrypt(key string, iv string, data string) (string, error) {
	_data := []byte(data)
	_key := []byte(key)
	_iv := []byte(iv)

	_data = pKCS7Padding(_data)
	block, err := aes.NewCipher(_key)
	if err != nil {
		return "", err
	}
	mode := cipher.NewCBCEncrypter(block, _iv)
	if len(_data)%mode.BlockSize() != 0 {
		return "", errors.New("input not full blocks")
	}
	mode.CryptBlocks(_data, _data)
	return base64.StdEncoding.EncodeToString(_data), nil
}

/**
aes解密
@param key string 密钥
@parma iv string 向量
@param data 数据 base64数据
*/
func AesDecrypt(key string, iv string, data string) (string, error) {
	_data, err := base64.StdEncoding.DecodeString(data)
	if err != nil {
		return "", err
	}
	_key := []byte(key)
	_iv := []byte(iv)

	block, err := aes.NewCipher(_key)
	if err != nil {
		return "", err
	}
	mode := cipher.NewCBCDecrypter(block, _iv)
	if len(_data)%mode.BlockSize() != 0 {
		return "", errors.New("input not full blocks")
	}
	mode.CryptBlocks(_data, _data)
	_data = pKCS7UnPadding(_data)
	return string(_data), nil
}
func pKCS7Padding(data []byte) []byte {
	padding := aes.BlockSize - len(data)%aes.BlockSize
	padText := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(data, padText...)
}
func pKCS7UnPadding(data []byte) []byte {
	length := len(data)
	unPadding := int(data[length-1])
	return data[:(length - unPadding)]
}
